package com.se.server;

import com.se.aiClient.AIClientUtils;
import com.se.common.*;
import com.se.db.*;
import com.se.exception.AIException;
import com.se.exception.ConnectionExistException;
import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.EOFException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.SocketException;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;

import static com.se.common.Constant.*;


public class ClientHandler implements Runnable {
    private final Socket socket;
    private static final Logger logger = LoggerFactory.getLogger(ClientHandler.class);
    private static final DbMessage dbMessage = DbMessage.getInstance();
    private static final DbUser dbuser = DbUser.getInstance();
    private static final boolean flag = true;
    private User user;
    private String CONNECTION_TYPE;

    public ClientHandler(Socket socket){
        this.socket = socket;
    }

    public ClientHandler(Socket socket, String CONNECTION_TYPE, User user) {
        this.socket = socket;
        this.CONNECTION_TYPE = CONNECTION_TYPE;
        this.user = user;
    }

    @Override
    public void run() {
        try {
            while(flag) {
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message msg = (Message) ois.readObject();

                processMessage(msg);

            }
        } catch (SocketException e) {
            if(ConnectionType.BASE_CONNECTION.equals(CONNECTION_TYPE)) {
                OnlineUserManager.getInstance().userOffline(user.getUserName());
                logger.info("用户 {} 异常下线\n{}", user.getUserName(), e.getMessage(), e);
            }
            else if(ConnectionType.FILE_CONNECTION.equals(CONNECTION_TYPE)) {
                logger.info("用户 {} 文件连接异常中断\n{}", user.getUserName(), e.getMessage(), e);
            }
        }
        catch (NullPointerException | SQLException e) {
            logger.error("数据库处理异常: {}", e.getMessage(), e);
            Server.runNewClient(socket, CONNECTION_TYPE, user);
        }
        catch (EOFException e) {
            if(ConnectionType.BASE_CONNECTION.equals(CONNECTION_TYPE)) {
                OnlineUserManager.getInstance().userOffline(user.getUserName());
                logger.info("用户 {} 已下线", user.getUserName());
            }
            else if(ConnectionType.FILE_CONNECTION.equals(CONNECTION_TYPE)) {
                logger.info("用户 {} 文件连接已关闭\n", user.getUserName());
            }
        }
        catch (Exception e) {
            logger.error("客户端处理异常: {}", e.getMessage(), e);
            Message error = new Message();
            error.setReceiveUser(user.getUserName());
            error.setMsgType(MessageType.MESSAGE_SERVER_ERROR);
            ServerUtils.sendMessage(socket, error);
        }
    }

    private String loginHandler(String userInfo) throws SQLException {
        String username = ServerUtils.parseUserInfo(userInfo).getString(USERNAME);
        String password = ServerUtils.parseUserInfo(userInfo).getString(PASSWORD);
        if((user = dbuser.getUser(username)) == null){
            return MessageType.MESSAGE_LOGIN_FAILURE_USER_NOT_EXIST;
        }

        if(!BCrypt.checkpw(password, user.getPassword())){
            return MessageType.MESSAGE_LOGIN_FAILURE_PASSWORD_NOT_CORRECT;
        }

        OnlineUserManager.getInstance().userOnline(username);
        CONNECTION_TYPE = ConnectionType.BASE_CONNECTION;

        return MessageType.MESSAGE_LOGIN_SUCCESS;
    }

    private String registerHandler(String userInfo) throws SQLException {
        String username = ServerUtils.parseUserInfo(userInfo).getString(USERNAME);
        String password = ServerUtils.parseUserInfo(userInfo).getString(PASSWORD);

        if((dbuser.getUser(username)) != null) {
            return MessageType.MESSAGE_REGISTER_USER_EXIST;
        }

        user = new User();
        user.setUserName(username);
        String hashPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        user.setPassword(hashPassword);
        dbuser.add(user);

        //添加用户信息
        UserInformation information = new UserInformation();
        information.setUserName(username);
        DbUserInformation.getInstance().addUserInformation(information);

        OnlineUserManager.getInstance().userOnline(user.getUserName());
        CONNECTION_TYPE = ConnectionType.BASE_CONNECTION;
        return MessageType.MESSAGE_REGISTER_SUCCESS;
    }

    private void processMessage(Message msg) throws SQLException {
        Message message = new Message();
        logger.info(msg.getContent());

        if (MessageType.MESSAGE_LOGIN_REQUEST.equals(msg.getMsgType())) {
            String userinfo = msg.getContent();
            String status = loginHandler(userinfo);
            message.setMsgType(status);

            if (MessageType.MESSAGE_LOGIN_SUCCESS.equals(status)
                    && !handleConnectSetup(userinfo)) {
                message.setMsgType(MessageType.MESSAGE_CLIENT_REQUEST_ERROR);
            }
            ServerUtils.sendMessage(socket, message);
            return;
        }

        if (MessageType.MESSAGE_REGISTER_REQUEST.equals(msg.getMsgType())) {
            String userInfo = msg.getContent();
            String status = registerHandler(userInfo);
            message.setMsgType(status);

            if (MessageType.MESSAGE_REGISTER_SUCCESS.equals(status)
                    && !handleConnectSetup(userInfo)) {
                message.setMsgType(MessageType.MESSAGE_CLIENT_REQUEST_ERROR);
            }
            ServerUtils.sendMessage(socket, message);

            return;
        }

        if (MessageType.MESSAGE_COMMON.equals(msg.getMsgType())) {
            Socket receiveSocket = Server.getBaseSocket(msg.getReceiveUser());
            dbMessage.add(msg);
            //添加我应该提醒的人
            user.addNotify(msg.getReceiveUser());
            dbuser.update(user, user.getUserName());

            OnlineUserManager.getInstance().updateUserActivity(user.getUserName());
            if (receiveSocket != null) {
                ServerUtils.sendMessage(receiveSocket, msg);
            }
            return;
        }

        if(MessageType.MESSAGE_USER_LIST_REQUEST.equals(msg.getMsgType())) {
            List<User> users = new ArrayList<>();
            List<String> friends = DbUserInformation.getInstance().get(user.getUserName()).getFriendList();
            for(var i : friends) {
                User friend = dbuser.getUser(i);
                if(friend != null) {
                    users.add(friend);
                }
            }

            message.setMsgType(MessageType.MESSAGE_USER_LIST_REQUEST);
            for(User i : users) {
                if(i.getNotifyList().contains(user.getUserName())) {
                    i.setNotify(true);
                }

                if(OnlineUserManager.getInstance().getOnlineUsers().contains(i.getUserName())) {
                    i.setStatus(ONLINE);
                }
                else{
                    i.setStatus(OFFLINE);
                }
                message.setContent(i.toString());
                ServerUtils.sendMessage(socket, message);
            }
            return;
        }

        if(MessageType.MESSAGE_GET_GROUP_MEMBERS.equals(msg.getMsgType())) {
            int groupId = Integer.parseInt(msg.getContent());
            List<User> members = new ArrayList<>();
            Group group = DbGroup.getInstance().get(groupId);
            for(var i : group.getAllUsers()) {
                User member = dbuser.getUser(i);
                if(member != null) {
                    members.add(member);
                }
            }

            message.setMsgType(MessageType.MESSAGE_GET_GROUP_MEMBERS);
            for(var i : members) {
                if(OnlineUserManager.getInstance().getOnlineUsers().contains(i.getUserName())) {
                    i.setStatus(ONLINE);
                }
                else {
                    i.setStatus(OFFLINE);
                }
                message.setContent(i.toString());
                ServerUtils.sendMessage(socket, message);
            }

            return;
        }

        if(MessageType.MESSAGE_MESSAGE_LIST_REQUEST.equals(msg.getMsgType())) {
            logger.info("进入消息列表处理");
            logger.info("消息发送者为: {}, 接收者为: {}", msg.getSendUser(), msg.getReceiveUser());
            List<Message> messageList;
            //如果是请求的是与个人用户的消息
            if(!isInteger(msg.getReceiveUser())) {
                //按时间顺序返回消息列表
                messageList = ServerUtils.mergeAndSortByTime(
                        DbMessage.getInstance().
                                getBySendUserAndReceiveUser(msg.getSendUser(), msg.getReceiveUser()),
                        DbMessage.getInstance().
                                getBySendUserAndReceiveUser(msg.getReceiveUser(), msg.getSendUser())
                );
            }
            else {
                List<Message> list1 = DbMessage.getInstance().getByReceiveUser(msg.getReceiveUser());
                //处理群组作为发送者的情况，群组只在请求AI解释消息时作为发送者
                List<Message> list2 = DbMessage.getInstance().getBySendUser(msg.getReceiveUser());
                messageList = ServerUtils.mergeAndSortByTime(list1, list2);
            }

            for(var i : messageList) {
                if(MessageType.MESSAGE_SENTENCE_EXPLAIN.equals(i.getMsgType())) {
                    logger.info("发送消息列表中的的ID为: {}", i.getId());
                }
                else if(MessageType.MESSAGE_FILE_IMAGE.equals(i.getMsgType())) {
                    FileMessage fileMessage = ServerUtils.getFile(i.getId(), i);
                    ServerUtils.sendMessage(socket, fileMessage);
                    continue;
                }
                else if(MessageType.MESSAGE_FILE.equals(i.getMsgType())) {
                    FileMessage fileMessage = new FileMessage();
                    fileMessage.setFileMessage(i);
                    fileMessage.setMsgType(MessageType.MESSAGE_FILE);
                    fileMessage.setContent(i.getContent());
                    ServerUtils.sendMessage(socket, fileMessage);
                    continue;
                }
                ServerUtils.sendMessage(socket, i);
            }

            //如果是群组的话移除群组提醒列表
            if(isInteger(msg.getReceiveUser())) {
                Group newGroup = DbGroup.getInstance().get(Integer.parseInt(msg.getReceiveUser()));
                newGroup.rmNotify(msg.getSendUser());
                DbGroup.getInstance().update(newGroup);

            }
            else {
                //用户请求了对方的消息数据，故将用户从对方的提醒列表中移除
                User newuser = DbUser.getInstance().getUser(msg.getReceiveUser());
                newuser.rmNotify(msg.getSendUser());
                DbUser.getInstance().update(newuser, newuser.getUserName());
            }

            return;
        }

        if(MessageType.MESSAGE_REMOVE_NOTIFY.equals(msg.getMsgType())) {
            //用户已经接收到了对方的消息，故将用户从对方的消息列表中移除(注意此处sendUser是对方)
            User newuser = DbUser.getInstance().getUser(msg.getSendUser());
            newuser.rmNotify(msg.getReceiveUser());
            DbUser.getInstance().update(newuser, newuser.getUserName());
            return;
        }

        if(MessageType.MESSAGE_CREATE_GROUP.equals(msg.getMsgType())) {
            Group group = new Group();
            group.setGroupOwner(msg.getSendUser());
            group.setGroupName(msg.getContent());
            int groupId = DbGroup.getInstance().getNewGroupId();
            group.setGroupId(groupId);
            //同步修改用户信息和群组信息
            UserInformation information = DbUserInformation.getInstance().get(msg.getSendUser());
            information.getOwnGroup().add(groupId);
            DbUserInformation.getInstance().update(information);
            DbGroup.getInstance().add(group);

            //将分配过groupId的群组返回客户端
            message.setContent(group.toString());
            message.setMsgType(MessageType.MESSAGE_CREATE_GROUP);

            ServerUtils.sendMessage(socket, message);
            return;
        }

        if(MessageType.MESSAGE_JOIN_GROUP.equals(msg.getMsgType())) {

            UserInformation information = DbUserInformation.getInstance().get(msg.getSendUser());

            int groupId = Integer.parseInt(msg.getContent());
            //判断群组是否存在
            Group group = DbGroup.getInstance().get(Integer.parseInt(msg.getContent()));
            if(group == null) {
                message.setMsgType(MessageType.MESSAGE_GROUP_NOT_EXIST);
                ServerUtils.sendMessage(socket, message);
                return;
            }

            //判断用户是否已经在群组中
            if(information.getMemberGroup().contains(groupId)
                    || information.getOwnGroup().contains(groupId)) {

                message.setMsgType(MessageType.MESSAGE_ALREADY_IN_GROUP);
                ServerUtils.sendMessage(socket, message);
                return;
            }
            //同步修改用户信息和群组信息
            information.getMemberGroup().add(groupId);
            DbUserInformation.getInstance().update(information);


            group.getGroupMembers().add(msg.getSendUser());
            DbGroup.getInstance().update(group);
            //返回加入成功的消息
            message.setMsgType(MessageType.MESSAGE_JOIN_GROUP);
            ServerUtils.sendMessage(socket, message);

            //广播群组更新
            broadcastGroupListUpdate(group);
            return;
        }

        if(MessageType.MESSAGE_GROUP_LIST_REQUEST.equals(msg.getMsgType())) {
            sendGroupList(msg.getSendUser());
            return;
        }

        if(MessageType.MESSAGE_GROUP_COMMON.equals(msg.getMsgType())) {
            Group group = DbGroup.getInstance().get(Integer.parseInt(msg.getReceiveUser()));
            //重设提醒列表（默认提醒所有群成员）
            group.resetNotifyList();
            DbGroup.getInstance().update(group);

            //更新消息
            dbMessage.add(msg);

            OnlineUserManager.getInstance().updateUserActivity(msg.getSendUser());

            Matcher matcher = ServerUtils.AT_PATTERN.matcher(msg.getContent());
            if(group.getGroupAI() != null
                    && !group.getGroupAI().isEmpty()) {
                String aiName = group.getGroupAI().split(" ")[1];
                String aiId = group.getGroupAI().split(" ")[0];
                logger.info("进入AI消息处理,ai名称: {}", aiName);
                while(matcher.find()) {
                    if(matcher.group(1).contains(aiName)) {
                        logger.info("匹配结果： {} ", matcher.group(1));
                        AIUser ai = DbAIUser.getInstance().get(aiId);
                        String prompt = AIClientUtils.promptCreator(ai.getAI_ID()
                                , msg.getSendUser() + "对你说: " + msg.getContent(),
                                ai.getApi_key(), ai.getAPI_URL(), ai.getModel(), ai.getTemperature()
                                , "你的名字叫做：" + aiName + ai.getPrimaryPrompt());
                        new Thread(() -> {
                            try {
                                String response = ServerUtils.getAiClient().generate(prompt, false);
                                Message aiMessage = new Message();
                                aiMessage.setContent(response);
                                aiMessage.setSendUser(aiName);
                                aiMessage.setReceiveUser(String.valueOf(group.getGroupId()));
                                aiMessage.setAI(true);
                                aiMessage.setMsgType(MessageType.MESSAGE_GROUP_COMMON);
                                aiMessage.setSendTime(LocalDateTime.now().format(DbUtils.formatter));
                                DbMessage.getInstance().add(aiMessage);

                                for(var i : group.getAllUsers()) {
                                    Socket receiveSocket = Server.getBaseSocket(i);
                                    if(receiveSocket != null) {
                                        ServerUtils.sendMessage(receiveSocket, aiMessage);
                                    }
                                }
                            } catch (AIException e) {
                                logger.warn("AI调用发生错误: {}", e.getMessage(), e);
                                message.setMsgType(MessageType.MESSAGE_BAD_AI_REQUEST);
                                message.setContent(e.getErrorType());
                                ServerUtils.sendMessage(socket, message);
                            } catch (Exception e) {
                                logger.warn("AI调用发生错误: {}", e.getMessage(), e);
                            }
                        }).start();
                    }
                }
            }

            //广播消息
            for(var i : group.getAllUsers()) {
                if(i.equals(msg.getSendUser())) {
                    continue;
                }

                Socket receiveSocket = Server.getBaseSocket(i);
                if(receiveSocket != null) {
                    ServerUtils.sendMessage(receiveSocket, msg);
                }
            }
            return;
        }

        if(MessageType.MESSAGE_REMOVE_GROUP_NOTIFY.equals(msg.getMsgType())) {
            //用户已经接收到了群组的消息，故将用户从群组的消息列表中移除(注意此处sendUser是群组)
            int groupId = Integer.parseInt(msg.getSendUser());
            Group group = DbGroup.getInstance().get(groupId);
            group.rmNotify(msg.getReceiveUser());
            DbGroup.getInstance().update(group);
            return;
        }

        //AI解释处理
        if(MessageType.MESSAGE_SENTENCE_EXPLAIN.equals(msg.getMsgType())) {
            AIUser ai = new AIUser(msg.getContent());
            JSONObject json = new JSONObject(msg.getContent());
            String content = json.getString(MESSAGE);

            String prompt = AIClientUtils.promptCreator(ai.getAI_ID(), "下面这句话中存在" +
                            "一些我不懂的网络用语，请你找到它或他们并帮我解释一下," +
                            "另外，请在回复中避免使用markdown文本格式" +
                            "保持纯文本输出: " + content,
                    ai.getApi_key(), ai.getAPI_URL(), ai.getModel(), ai.getTemperature(), null);
            new Thread(() -> {
                try {
                    String response = ServerUtils.getAiClient().generate(prompt, true);

                    message.setContent(response);
                    message.setMsgType(msg.getMsgType());
                    message.setAI(true);
                    message.setCurrentDisplayIndex(0);
                    message.setSendUser(msg.getSendUser());
                    message.setReceiveUser(msg.getReceiveUser());
                    message.getId();
                    logger.info("发送消息的ID为: {}", message.getId());
                    message.setSendTime(LocalDateTime.now().format(DbUtils.formatter));
                    DbMessage.getInstance().add(message);

                    ServerUtils.sendMessage(socket, message);
                } catch (AIException e) {
                    logger.warn("AI调用发生错误: {}", e.getMessage(), e);
                    message.setMsgType(MessageType.MESSAGE_BAD_AI_REQUEST);
                    message.setContent(e.getErrorType());
                    ServerUtils.sendMessage(socket, message);
                } catch (Exception e) {
                    logger.warn("AI调用发生错误: {}", e.getMessage(), e);
                }
            }).start();
            return;
        }

        if(MessageType.MESSAGE_CREATE_FILE_CONNECTION_REQUEST.equals(msg.getMsgType())) {
            String username = ServerUtils.parseUserInfo(msg.getContent()).getString(USERNAME);
            String password = ServerUtils.parseUserInfo(msg.getContent()).getString(PASSWORD);
            this.user = new User(username, password);
            this.CONNECTION_TYPE = ConnectionType.FILE_CONNECTION;
            message.setMsgType(MessageType.MESSAGE_CREATE_FILE_CONNECTION_REQUEST);

            ServerUtils.sendMessage(socket, message);
            return;
        }

        if(MessageType.MESSAGE_FILE.equals(msg.getMsgType())) {
            if(msg instanceof FileMessage file) {

                ServerUtils.addFile(msg.getId(), file);

                //由于普通文件需要用户中主动申请，所以先卸载文件内容便于操作
                FileMessage unLoadFile = file.unLoad();

                DbMessage.getInstance().add(unLoadFile);
                if(!isInteger(unLoadFile.getReceiveUser())) {
                    Socket receiveSocket = Server.getBaseSocket(msg.getReceiveUser());
                    //更新消息通知
                    user.addNotify(msg.getReceiveUser());
                    dbuser.update(user, user.getUserName());

                    //更新用户活动(虽然好像没什么屌用
                    OnlineUserManager.getInstance().updateUserActivity(user.getUserName());
                    if (receiveSocket != null) {
                        ServerUtils.sendMessage(receiveSocket, unLoadFile);
                    }
                }
                else {
                    Group group = DbGroup.getInstance().get(Integer.parseInt(unLoadFile.getReceiveUser()));
                    //重设提醒列表（默认提醒所有群成员）
                    group.resetNotifyList();
                    DbGroup.getInstance().update(group);

                    OnlineUserManager.getInstance().updateUserActivity(unLoadFile.getSendUser());

                    for(var i : group.getAllUsers()) {
                        if(i.equals(unLoadFile.getSendUser())) {
                            continue;
                        }

                        Socket receiveSocket = Server.getBaseSocket(i);
                        if(receiveSocket != null) {
                            ServerUtils.sendMessage(receiveSocket, unLoadFile);
                        }
                    }
                }

            }
            else {
                //异常回送
                message.setMsgType(MessageType.MESSAGE_SERVER_ERROR);
                ServerUtils.sendMessage(socket, message);
            }
            return;
        }

        if(MessageType.MESSAGE_FILE_IMAGE.equals(msg.getMsgType())) {
            //图片文件可以主动转发
            if(msg instanceof FileMessage file) {
                //虽然主动转发了，但还是要存的，万一他删了呢
                ServerUtils.addFile(msg.getId(), file);
                DbMessage.getInstance().add(file.unLoad());
                if(!isInteger(file.getReceiveUser())) {
                    Socket receiveSocket = Server.getBaseSocket(msg.getReceiveUser());
                    //更新消息通知
                    user.addNotify(msg.getReceiveUser());
                    dbuser.update(user, user.getUserName());

                    //更新用户活动(虽然好像没什么屌用
                    OnlineUserManager.getInstance().updateUserActivity(user.getUserName());
                    if (receiveSocket != null) {
                        ServerUtils.sendMessage(receiveSocket, file);
                    }
                }
                else {
                    Group group = DbGroup.getInstance().get(Integer.parseInt(file.getReceiveUser()));
                    //重设提醒列表（默认提醒所有群成员）
                    group.resetNotifyList();
                    DbGroup.getInstance().update(group);

                    //更新消息
                    dbMessage.add(file.unLoad());

                    OnlineUserManager.getInstance().updateUserActivity(file.getSendUser());

                    for(var i : group.getAllUsers()) {
                        if(i.equals(file.getSendUser())) {
                            continue;
                        }

                        Socket receiveSocket = Server.getBaseSocket(i);
                        if(receiveSocket != null) {
                            ServerUtils.sendMessage(receiveSocket, file);
                        }
                    }
                }
            }
            else {

                message.setMsgType(MessageType.MESSAGE_SERVER_ERROR);
                ServerUtils.sendMessage(socket, message);
            }
            return;
        }

        if(MessageType.MESSAGE_FILE_DOWNLOAD_REQUEST.equals(msg.getMsgType())) {

            FileMessage fileMessage = ServerUtils.getFile(msg.getId(), msg);
            fileMessage.setMsgType(MessageType.MESSAGE_FILE);
            ServerUtils.sendMessage(socket, fileMessage);
            //发完文件后就把线程关了
            message.setMsgType(MessageType.MESSAGE_CLOSE_FILE_CONNECTION_REQUEST);
            ServerUtils.sendMessage(socket, message);
            return;
        }

        if(MessageType.MESSAGE_ADD_AI_ROBOT.equals(msg.getMsgType())) {
            JSONObject json = new JSONObject(msg.getContent());
            int groupId = json.getInt(MESSAGE);
            Group group = DbGroup.getInstance().get(groupId);
            AIUser bot = new AIUser(msg.getContent());
            //本来应该要做合法性检测的，但是懒得写了
            DbAIUser.getInstance().add(bot);
            //同步更新群组和个人信息
            group.setGroupAI(bot.getAI_ID() + " " + bot.getAI_name());
            DbGroup.getInstance().update(group);

            UserInformation information = DbUserInformation.getInstance().get(group.getGroupOwner());
            information.addAI(bot.getAI_ID());
            DbUserInformation.getInstance().update(information);

            broadcastGroupListUpdate(group);
            return;
        }

        if(MessageType.MESSAGE_SEARCH_FRIEND.equals(msg.getMsgType())) {
            List<User> result = dbuser.search(msg.getContent());
            message.setMsgType(MessageType.MESSAGE_SEARCH_FRIEND);
            for(var i : result) {
                if(i.getUserName().equals(user.getUserName())) {
                    continue;
                }
                if(OnlineUserManager.getInstance().getOnlineUsers().contains(i.getUserName())) {
                    i.setStatus(ONLINE);
                }
                else {
                    i.setStatus(OFFLINE);
                }
                message.setContent(i.toString());
                ServerUtils.sendMessage(socket, message);
            }
            return;
        }

        if(MessageType.MESSAGE_ADD_FRIEND.equals(msg.getMsgType())) {
            //注意此处添加好友申请是在被申请者的信息中添加上申请者
            UserInformation information = DbUserInformation.getInstance().get(msg.getReceiveUser());
            information.addFriendRequest(msg.getSendUser());
            DbUserInformation.getInstance().update(information);
            if(OnlineUserManager.getInstance().getOnlineUsers().contains(msg.getReceiveUser())) {
                ServerUtils.sendMessage(Objects.requireNonNull(Server.getBaseSocket(msg.getReceiveUser())), msg);
            }
            return;
        }

        if(MessageType.MESSAGE_GET_FRIEND_REQUEST.equals(msg.getMsgType())) {
            UserInformation information = DbUserInformation.getInstance().get(msg.getSendUser());
            logger.info("申请好友的人数为: {}", information.getFriendRequest().size());
            message.setMsgType(MessageType.MESSAGE_ADD_FRIEND);
            message.setReceiveUser(msg.getSendUser());
            for(var i : information.getFriendRequest()) {
                message.setSendUser(i);
                ServerUtils.sendMessage(socket, message);
            }
        }

        if(MessageType.MESSAGE_AGREE_FRIEND_REQUEST.equals(msg.getMsgType())) {
            UserInformation receiveInformation = DbUserInformation.getInstance().get(msg.getReceiveUser());
            UserInformation sendInformation = DbUserInformation.getInstance().get(msg.getSendUser());
            sendInformation.getFriendRequest().remove(msg.getReceiveUser());
            sendInformation.addFiend(msg.getReceiveUser());
            receiveInformation.addFiend(msg.getSendUser());
            DbUserInformation.getInstance().update(sendInformation);
            DbUserInformation.getInstance().update(receiveInformation);

            message.setMsgType(MessageType.MESSAGE_USER_LIST_UPDATE);
            User receiveUser = new User();
            receiveUser.setUserName(msg.getReceiveUser());
            if(OnlineUserManager.getInstance().getOnlineUsers().contains(msg.getReceiveUser())) {
                receiveUser.setStatus(ONLINE);
            }
            else {
                receiveUser.setStatus(OFFLINE);
            }
            receiveUser.setNotify(false);
            message.setContent(receiveUser.toString());
            ServerUtils.sendMessage(socket, message);

            if(receiveUser.getStatus().equals(ONLINE)) {
                User sendUser = new User();
                sendUser.setUserName(msg.getSendUser());
                sendUser.setStatus(ONLINE);
                sendUser.setNotify(false);
                message.setContent(sendUser.toString());
                ServerUtils.sendMessage(Objects.requireNonNull(Server.getBaseSocket(msg.getReceiveUser())), message);
            }
            return;
        }

        if(MessageType.MESSAGE_REFUSE_FRIEND_REQUEST.equals(msg.getMsgType())) {
            UserInformation information = DbUserInformation.getInstance().get(msg.getSendUser());
            information.getFriendRequest().remove(msg.getReceiveUser());
            DbUserInformation.getInstance().update(information);
        }
    }

    private void broadcastGroupListUpdate(Group group) {
        Message message = new Message();
        message.setMsgType(MessageType.MESSAGE_GROUP_UPDATE);

        for(var i : group.getAllUsers()) {
            if(OnlineUserManager.getInstance().getOnlineUsers().contains(i)) {
                message.setContent(group.toString());
                ServerUtils.sendMessage(Objects.requireNonNull(Server.getBaseSocket(i)), message);
            }
        }
    }

    private void sendGroupList(String username) throws SQLException {
        UserInformation information = DbUserInformation.getInstance().get(username);
        Group group;
        Message message = new Message();
        //先发送作为群主的群组
        for(var i : information.getOwnGroup()) {
            group = DbGroup.getInstance().get(i);
            //如果群组有尚待接受的群组消息
            if(group.getNotifyList().contains(username)) {
                group.setNotify(true);
            }
            message.setContent(group.toString());
            message.setMsgType(MessageType.MESSAGE_GROUP_LIST_REQUEST);
            ServerUtils.sendMessage(socket, message);
            message = new Message();
        }
        //再发送作为群成员的群组
        for(var i : information.getMemberGroup()) {
            group = DbGroup.getInstance().get(i);
            //如果该用户在群组中有尚待接受的群组消息
            if(group.getNotifyList().contains(username)) {
                group.setNotify(true);
            }
            message.setContent(group.toString());
            message.setMsgType(MessageType.MESSAGE_GROUP_LIST_REQUEST);
            ServerUtils.sendMessage(socket, message);
            message = new Message();
        }
    }

    public static boolean isInteger(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private boolean handleConnectSetup(String userinfo){
        try{
            Server.addConnection(ServerUtils.parseUserInfo(userinfo).
                    getString(USERNAME), socket, ConnectionType.BASE_CONNECTION);
        } catch (ConnectionExistException e) {
            logger.error("尝试建立已存在的连接: {}", userinfo);
            return false;
        }
        return true;
    }
}
